package cn.jia.hrm.service.impl;

import cn.jia.hrm.CourseDoc;
import cn.jia.hrm.CourseESQuery;
import cn.jia.hrm.HighlightResultMapper;
import cn.jia.hrm.PageList;
import cn.jia.hrm.repository.RepositoryElasticSearchRepository;
import cn.jia.hrm.service.ISearchService;
import cn.jia.hrm.util.AggrbucketVo;
import cn.jia.hrm.util.SearchPageList;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SearchServiceimpl implements ISearchService {

    @Autowired
    private RepositoryElasticSearchRepository repositoryElasticSearchRepository;

    @Autowired
    private HighlightResultMapper highlightResultMapper;

    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;

    @Override
    public void save(CourseDoc courseDoc) {  //保存在ES中去
        System.out.println("111111111111111111");
        System.out.println(courseDoc);
        repositoryElasticSearchRepository.save(courseDoc);
    }

    @Override
    public void delete(Long id) {

        repositoryElasticSearchRepository.deleteById(id);
    }

    @Override
    public PageList searchCourse(CourseESQuery query) {
        //查询的构建器
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        queryBuilder.withPageable(PageRequest.of(query.getPage()-1,query.getRows()));   //public static PageRequest of(int page, int size) { return of(page, size, Sort.unsorted());   }
        //排序   字段不为空就执行
        if(StringUtils.hasText(query.getSortField())){

            String sortField = "saleCount";
            switch (query.getSortField()){
                case "xp": sortField = "onlineTime";break;
                case "xl": sortField = "saleCount";break;
                case "pl": sortField = "commentCount";break;
                case "jg": sortField = "price";break;
                case "rq": sortField = "viewCount";break;
            }
            //倒排
            SortOrder sortOrder = SortOrder.DESC;                             //忽略大小写
            if(StringUtils.hasText(query.getSortType()) && query.getSortType().equalsIgnoreCase("asc")){
                sortOrder = SortOrder.ASC;
            }
            queryBuilder.withSort(SortBuilders.fieldSort(sortField).order(sortOrder));
        }
              //查询的条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();


        //keyword:关键字查询
        if(StringUtils.hasText(query.getKeyword())){
            boolQueryBuilder.must(QueryBuilders.matchQuery("name",query.getKeyword()));
        }

        //courseTypeId ;
        if(null != query.getCourseTypeId()){
            boolQueryBuilder.filter(QueryBuilders.termQuery("courseTypeId",query.getCourseTypeId()));
        }

        //gradeName ;
        if(StringUtils.hasText(query.getGradeName())){
            boolQueryBuilder.filter(QueryBuilders.termQuery("gradeName",query.getGradeName()));
        }

        //tenantName
        if(StringUtils.hasText(query.getTenantName())){
            boolQueryBuilder.filter(QueryBuilders.termQuery("tenantName",query.getTenantName()));
        }

        //priceMax;
        if(null != query.getPriceMax()){
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").lte(query.getPriceMax()));
        }

        //priceMin;
        if(null != query.getPriceMin()){
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(query.getPriceMin()));
        }

        //添加查询条件
        queryBuilder.withQuery(boolQueryBuilder);


        HighlightBuilder.Field highlightBuilder = new HighlightBuilder.Field("name").preTags("<font style='color:red'><b>")
                .postTags("</b></font>");
        queryBuilder.withHighlightFields(highlightBuilder);  //什么字段的名字需要高光

        setAggr(queryBuilder);//添加聚和

        //执行查询
        AggregatedPage<CourseDoc> page = elasticsearchTemplate.queryForPage(queryBuilder.build(), CourseDoc.class, highlightResultMapper);


        //聚合结果
        Aggregations aggregations = page.getAggregations();

        //封装成结果Map
        Map<String,List<AggrbucketVo>> aggrMap = new HashMap<>();

        //((StringTerms) aggregations.aggregations.get(0)).getBuckets().get(0).getDocCount()

        //这里是 aggregations 的集合，包含 2 个聚合结果
        aggregations.asList().forEach(aggregation -> {

            //这里 aggregation 是 一个聚合结果，其中有个 getBuckets 是集合结果列表
            List<AggrbucketVo> aggrbucketVoList = new ArrayList<>();

            ((StringTerms)aggregation).getBuckets().forEach(bucket -> {
                //bucket就是结果明细
                AggrbucketVo aggrbucketVo = new AggrbucketVo((String) bucket.getKey(), bucket.getDocCount());
                aggrbucketVoList.add(aggrbucketVo);
            });

            //key是集合的名字，
            aggrMap.put(aggregation.getName(),aggrbucketVoList);
        });
        System.out.println(aggrMap);



        /*elasticsearchTemplate.query*/
        //Page<CourseDoc> page = repositoryElasticSearchRepository.search(queryBuilder.build());
      //  return new PageList(page.getTotalElements(),page.getContent());
        return new SearchPageList(page.getTotalElements(),page.getContent(),aggrMap);
    }

    private void setAggr(NativeSearchQueryBuilder queryBuilder) {
        //等级集合聚合
        TermsAggregationBuilder gradeNameAgg =
                AggregationBuilders.terms("gradeNameAgg").field("gradeName").size(10);

        //机构名聚合
        TermsAggregationBuilder tenantNameAgg =
                AggregationBuilders.terms("tenantNameAgg").field("tenantName").size(10);

        queryBuilder.addAggregation(gradeNameAgg).addAggregation(tenantNameAgg);
    }

}
